package cn.edu.fudan.classifier;

import cn.edu.fudan.data.ExtractFeature;
import cn.edu.fudan.data.HandelFeature;
import cn.edu.fudan.data.HandleDistance;
import cn.edu.fudan.data.SlideWindow;
import cn.edu.fudan.tools.GetConfig;
import cn.edu.fudan.type.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Classifiers {
	
	private List<DataItem> data;
	private BeginEndTime bet;
	
	
	public Classifiers(List<DataItem> data, BeginEndTime bet){
		this.bet = bet;
		this.data = data;
	}
	
	public double PAMAPClassifier(Params params){
		double accuracy = 0;
		Config config;
		try {
			config = new GetConfig().getConfig();
			
			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature= new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();
			
			if(data.size() > 0 && bet.getBegin()*bet.getEnd() != 0){
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(), config.getInterval());
				List<List<DataItem>> datas = slideWindow.extractWindow(feature.getAbnormal(), Math.round(params.getWindow_length()));
				long mark_time = 0;
				List<List<Double>> maps = new ArrayList<>();
				List<List<Double>> maps_posi = new ArrayList<>();
				for(int i = 0; i < datas.size(); i ++){
					if(datas.get(i).get(0).getTimestamp() > mark_time){
						mark_time = datas.get(i).get(0).getTimestamp();
						List<Double> map = handelFeature.handleFeature(datas.get(i), Math.round(params.getN_segment()));					
						
						if(mark_time >= bet.getBegin()*10000 && mark_time < bet.getEnd()*10000){
							maps_posi.add(map);
							continue;						
						}

						maps.add(map);
					}
				}
				
				List<List<DataItem>> map_distance = handleDistance.calDistance(maps_posi, maps, 0);
				accuracy = handleDistance.calAccuracy(map_distance, config.getK());
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return accuracy;
	}

    public double PAMAPPaaClassifier(Params params){  //用paa表示特征
        double accuracy = 0;
        Config config;
        try {
            config = new GetConfig().getConfig();

            ExtractFeature extractFeature = new ExtractFeature();
            HandelFeature handelFeature= new HandelFeature();
            SlideWindow slideWindow = new SlideWindow();
            HandleDistance handleDistance = new HandleDistance();

            if(data.size() > 0 && bet.getBegin()*bet.getEnd() != 0){
                //Feature paafeature = extractFeature.getPaaFeature(data,config.getWindow_length()/config.getN_segment());
                Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(), config.getInterval());
                List<List<DataItem>> datas = slideWindow.extractWindow(feature.getAbnormal(), Math.round(params.getWindow_length()));
                long mark_time = 0;
                List<List<Double>> maps = new ArrayList<>();
                List<List<Double>> maps_posi = new ArrayList<>();
                for(int i = 0; i < datas.size(); i++){
                    if(datas.get(i).get(0).getTimestamp() > mark_time){
                        mark_time = datas.get(i).get(0).getTimestamp();
                        //List<Double> map = handelFeature.handleFeature(datas.get(i), Math.round(params.getN_segment()));
                        List<Double> map = handelFeature.handlePaaFeature(datas.get(i), Math.round(params.getN_segment())); //paa那里不好？

                        if(mark_time >= bet.getBegin()*10000 && mark_time < bet.getEnd()*10000){
                            maps_posi.add(map);
                            continue;
                        }

                        maps.add(map);
                    }
                }

                List<List<DataItem>> map_distance = handleDistance.calDistance(maps_posi, maps, 0);
                accuracy = handleDistance.calAccuracy(map_distance, config.getK());
            }
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        return accuracy;
    }

	public double PAMAPPaaClassifier(Params params, int N_segment ){  //用paa表示特征,段数自己设的函数
		double accuracy = 0;
		Config config;
		try {
			config = new GetConfig().getConfig();

			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature= new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();

			if(data.size() > 0 && bet.getBegin()*bet.getEnd() != 0){
				//Feature paafeature = extractFeature.getPaaFeature(data,config.getWindow_length()/config.getN_segment());
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(), config.getInterval());
				List<List<DataItem>> datas = slideWindow.extractWindow(feature.getAbnormal(), Math.round(params.getWindow_length()));
				long mark_time = 0;
				List<List<Double>> maps = new ArrayList<>();
				List<List<Double>> maps_posi = new ArrayList<>();
				for(int i = 0; i < datas.size(); i++){
					if(datas.get(i).get(0).getTimestamp() > mark_time){
						mark_time = datas.get(i).get(0).getTimestamp();
						//List<Double> map = handelFeature.handleFeature(datas.get(i), Math.round(params.getN_segment()));
						List<Double> map = handelFeature.handlePaaFeature(datas.get(i), Math.round(N_segment)); //paa那里不好？

						if(mark_time >= bet.getBegin()*10000 && mark_time < bet.getEnd()*10000){
							maps_posi.add(map);
							continue;
						}

						maps.add(map);
					}
				}

				List<List<DataItem>> map_distance = handleDistance.calDistance(maps_posi, maps, 0);
				accuracy = handleDistance.calAccuracy(map_distance, config.getK());
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return accuracy;
	}

	public double PAMAPSRDClassifier(Params params, int N_segment ){  //用分段标准差表示特征,段数自己设的参数
		double accuracy = 0;
		Config config;
		try {
			config = new GetConfig().getConfig();

			ExtractFeature extractFeature = new ExtractFeature();
			HandelFeature handelFeature= new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();

			if(data.size() > 0 && bet.getBegin()*bet.getEnd() != 0){
				//Feature paafeature = extractFeature.getPaaFeature(data,config.getWindow_length()/config.getN_segment());
				Feature feature = extractFeature.getFeature(data, config.getThreshold_window(), config.getProbability(), config.getInterval());
				List<List<DataItem>> datas = slideWindow.extractWindow(feature.getAbnormal(), Math.round(params.getWindow_length()));
				long mark_time = 0;
				List<List<Double>> maps = new ArrayList<>();
				List<List<Double>> maps_posi = new ArrayList<>();
				for(int i = 0; i < datas.size(); i++){
					if(datas.get(i).get(0).getTimestamp() > mark_time){
						mark_time = datas.get(i).get(0).getTimestamp();
						//List<Double> map = handelFeature.handleFeature(datas.get(i), Math.round(params.getN_segment()));
						//List<Double> map = handelFeature.handlePaaFeature(datas.get(i), Math.round(N_segment)); //paa那里不好？
						List<Double> map = handelFeature.handleSrdFeature(datas.get(i), Math.round(N_segment));

						if(mark_time >= bet.getBegin()*10000 && mark_time < bet.getEnd()*10000){
							maps_posi.add(map);
							continue;
						}

						maps.add(map);
					}
				}

				List<List<DataItem>> map_distance = handleDistance.calDistance(maps_posi, maps, 0);
				accuracy = handleDistance.calAccuracy(map_distance, config.getK());
			}
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return accuracy;
	}
}	
